#include "app_mqtt.h"
#include "MQTTClient.h"
#include "log.h"

// 声明mqtt客户端句柄
MQTTClient mqtt_client;

// 连接参数模板
MQTTClient_connectOptions conn_opt = MQTTClient_connectOptions_initializer;
// 发布消息的模板
MQTTClient_message pubmsg = MQTTClient_message_initializer;

// 处理回调的函数指针（外部注册）
static int (*recv_callback)(char *data, int len);

// 失联回调
void app_mqtt_connectionLost(void *context, char *cause)
{
    log_error(" connection lost %s: ", cause);
}


// 回执到到达时才会触发  发送消息时 设置qos 1或2
void app_mqtt_deliveryComplete(void *context, MQTTClient_deliveryToken dt)
{
    log_info("  消息已发送  ");
}
// 消息到达回调
int app_mqtt_messageArrived(void *context, char *topicName, int topicLen, MQTTClient_message *message)
{
    // 1 把数据从message结构体中提取
    // 2 放入数据接收的处理函数（外部注册）
    if(recv_callback==NULL)
    {
        MQTTClient_freeMessage(&message);
        return 0;
    }
    int ret = recv_callback(message->payload, message->payloadlen);
    MQTTClient_freeMessage(&message);

    if (ret == 0)
    {
        return 1;
    }
    else
    {
        return 0;
    }
}

/**
 * @brief 初始化mqtt
 * 1 创建客户端  给客户端句柄（空）  给服务端地址
 * 2 设置回调函数 3个 失联、数据到达、 发送成功回调
 * 3 和服务端建立连接
 * 4 订阅某个主题
 */
int app_mqtt_init()
{
    // * 1 创建客户端  给客户端句柄（空）  给服务端地址
    int ret = MQTTClient_create(&mqtt_client, MQTT_SERVER_URI, CLIENT_ID, MQTTCLIENT_PERSISTENCE_NONE, NULL);
    if (ret == -1)
    {
        log_error("初始化失败");
        return -1;
    }
    //    * 2 设置回调函数 3个 失联、数据到达、 发送成功回调
    MQTTClient_setCallbacks(mqtt_client, NULL, app_mqtt_connectionLost, app_mqtt_messageArrived, app_mqtt_deliveryComplete);

    //    * 3 和服务端建立连接
    ret = MQTTClient_connect(mqtt_client, &conn_opt);
    if (ret == 0)
    {
        log_info("mqtt连接成功");
    }
    else
    {
        log_error("mqtt连接失败");
        return -1;
    }

    //    * 4 订阅某个主题
    ret = MQTTClient_subscribe(mqtt_client, MQTT_SUBSCRIBE_TOPIC, MQTT_QOS);
    if (ret == 0)
    {
        log_info("mqtt订阅成功");
    }
    else
    {
        log_error("mqtt订阅失败");
        return -1;
    }

    return 0;
}

/**
 * @brief 发送数据
 */
int app_mqtt_send(char *data, int data_len)
{
    pubmsg.payload = data;
    pubmsg.payloadlen = data_len;
    pubmsg.qos = MQTT_QOS;
    int ret= MQTTClient_publishMessage(mqtt_client, MQTT_PUBLISH_TOPIC, &pubmsg,NULL);
    if(ret==-1)
    {
        log_error("mqtt发送失败");
        return -1;
    }
    return 0;
}

/**
 * @brief  向mqtt模块注册接收数据的处理回调
 */
void app_mqtt_register_recv_callback(int (*callback)(char *, int))
{
    recv_callback = callback;
}

/**
 * @brief 销毁客户端
 */
void app_mqtt_destroy()
{
    MQTTClient_disconnect(mqtt_client, 1000);
    MQTTClient_destroy(&mqtt_client);
}